<?php

namespace App\Listener;

use App\Event\RechargeEvent;
use App\Event\RegDoneEvent;
use App\Helpers\NumberUtil;
use App\Model\Spread\SpreadAccount;
use App\Model\Spread\SpreadLog;
use App\Model\Spread\StatCpa;
use App\Model\SpreadOrderLog;
use App\Model\StatCps;
use App\Service\Common\SpreadCoinOperateService;
use Hyperf\Event\Contract\ListenerInterface;
use Hyperf\Event\Annotation\Listener;

/**
 * cps
 * @Listener
 */
class CpsListener implements ListenerInterface
{

    public int $userId;

    public string $eventType;

    public function listen(): array
    {
        // 返回一个该监听器要监听的事件数组，可以同时监听多个事件
        return [
            //注册事件
            RegDoneEvent::class,
            //充值事件
            RechargeEvent::class
        ];
    }

    public function process(object $event)
    {
        if (!$event->userId && $event->userId == 0) {
            return;
        }
        log_info(__CLASS__.'event'.json_encode($event));

        $this->userId = (int)$event->userId;
        $this->eventType = $event->eventType;;

        switch ($event->eventType)
        {
            case 'recharge':
                $this->rechargeRmb = $event->rechargeRmb;
                $this->orderId = $event->orderId;
                $this->recharge();
                break;
            case 'reg_done':
                $this->regDone();
                break;
        }
    }

    private function regDone()
    {
	$data = SpreadLog::where('user_id',$this->userId)->first()??[];
	 if (empty($data))
        {
            return;
        }
	
	log_info(__CLASS__.json_encode($data->toArray()));
        $spreadInfo = SpreadAccount::where('id',$data->s_id)->first();

        if (empty($data))
        {
            return;
        }

        if ($data->is_activate == 1)
        {
            return;
        }

        if ($spreadInfo->channel_type != 2) {
            return;
        }

//        $data = $data->toArray();

        $data->is_activate = 1;

        $data->save();



        $statInfo = $this->getStatData($spreadInfo->id,$spreadInfo->parent_id);
        $statInfo->reg_num = $statInfo->reg_num + 1;

        $statInfo->save();
    }

    private function recharge()
    {
        $data = SpreadLog::where('user_id',$this->userId)->first();

        if (empty($data)) {
            return;
        }

        if ($data->is_activate != 1) {
            return;
        }

        $spreadInfo = SpreadAccount::where('id',$data->s_id)->first();

        $cpsInfo = SpreadOrderLog::where('order_id',$this->orderId)->first();

        $spreadOrderLogModel = new SpreadOrderLog();
        $spreadOrderLogModel->s_id = $spreadInfo->id;
        $spreadOrderLogModel->order_id = $this->orderId;
        $spreadOrderLogModel->user_id = $this->userId;
        $spreadOrderLogModel->recharge_rmb = $this->rechargeRmb;
        $spreadOrderLogModel->k = 1;
        $spreadOrderLogModel->dt = date('Y-m-d');

        $spreadOrderLogModel->save();

        if ($spreadInfo->channel_type == 1) {
            $this->cpaRecharge($spreadInfo);
            return;
        }


        if (empty($spreadInfo) || $spreadInfo->channel_type != 2 || !empty($cpsInfo)) {
            return;
        }


        $statInfo = $this->getStatData($spreadInfo->id,$spreadInfo->parent_id);

        //扣量逻辑
        if ($spreadInfo->cps_discount_proportion > 0) {
            $flag = 0;

            // x扣 1 x=1  直接扣量
            if ($spreadInfo->cps_discount_proportion == 1) {
                $flag = 1;
            }

            // x扣 1 走算法计算 x != 1
            if ($flag != 1)
            {
                $rechargeNum = SpreadOrderLog::where('s_id',$spreadInfo->id)->where('dt',date('Y-m-d'))->count('id') ?? 0;

                $numerator = fmod($rechargeNum/$spreadInfo->cps_discount_proportion,1) * $spreadInfo->cps_discount_proportion;

                if ($numerator == 1)
                {
                    $flag = 1;
                }
            }

            //  扣量逻辑
            if ($flag == 1){
                $spreadOrderLogModel->k = 2;
                $spreadOrderLogModel->save();

                $statInfo->num_k = $statInfo->num_k + 1;
                $statInfo->recharge_k = bcadd($statInfo->recharge_k,$this->rechargeRmb,2);
                $statInfo->save();
                //扣量直接跳出 不计算分成 不统计充值金额
                return;
            }
        }

        $shareDif = 0;

        if ($spreadInfo->parent_id > 0) {
            $parentInfo = SpreadAccount::where('id',$spreadInfo->parent_id)->first();
            $shareDif = $parentInfo->share_rate - $spreadInfo->share_rate;
        }

        //当级算法
        $share = bcmul(bcdiv($spreadInfo->share_rate,100,2),$this->rechargeRmb,2);
//        (new SpreadCoinOperateService())->inc($spreadInfo->id,$share,$this->orderId,$this->orderId.'充值返佣金');

        $statInfo->recharge = bcadd($statInfo->recharge,$this->rechargeRmb,2);
        $statInfo->income = bcadd($statInfo->income,$share,2);
        $statInfo->num = $statInfo->num + 1;

        $statInfo->save();

        //上级算法
        if ($shareDif <= 0) {
            return;
        }

        $parentStat = $this->getStatData($spreadInfo->parent_id,0);

        $parentShare = bcmul(bcdiv($shareDif,100,2),$this->rechargeRmb, 2);
//        (new SpreadCoinOperateService())->inc($spreadInfo->parent_id,$parentShare,$this->orderId,'下级订单'.$this->orderId.'充值返佣金');

        $parentStat->child_income = bcadd($parentStat->child_income,$parentShare,2);
        $parentStat->save();
    }

    private function cpaRecharge($spreadInfo)
    {
        $statInfo = $this->getCpaStatData($spreadInfo->id,$spreadInfo->parent_id);

        $statInfo->recharge = bcadd($statInfo->recharge,$this->rechargeRmb,2);

        $statInfo->save();
    }

    /**
     * @return StatCps|\Hyperf\Database\Model\Builder|\Hyperf\Database\Model\Model|object|null
     */
    private function getStatData($sId,$pId)
    {
        $statInfo = StatCps::where('s_id',$sId)->where('dt',date('Y-m-d'))->first();
        if (!$statInfo)
        {
            $statInfo = new StatCps();

            $statInfo->s_id = $sId;
            $statInfo->p_id =$pId;

            $statInfo->dt = date('Y-m-d');
//            $statInfo->reg = 0;
            $statInfo->recharge = 0;
            $statInfo->recharge_k = 0;
            $statInfo->income = 0;
            $statInfo->child_income = 0;

            $statInfo->num = 0;
            $statInfo->num_k = 0;
            $statInfo->reg_num = 0;

            $statInfo->is_settle = 0;

            $statInfo->save();
        }

        return $statInfo;
    }

    private function getCpaStatData($sId,$pId)
    {
        $statInfo = StatCpa::where('s_id',$sId)->where('dt',date('Y-m-d'))->first();

        if (!$statInfo)
        {
            $statInfo = new StatCpa();

            $statInfo->s_id = $sId;
            $statInfo->p_id =$pId;

            $statInfo->dt = date('Y-m-d');
//            $statInfo->reg = 0;
            $statInfo->reg = 0;
            $statInfo->reg_k = 0;

            $statInfo->recharge = 0;

            $statInfo->is_settle = 0;

            $statInfo->save();
        }

        return $statInfo;
    }
}
